package com.smrtcold.dev.service.base;


import com.smrtcold.dev.dto.dev.base.Point;
import com.smrtcold.dev.dto.dev.base.PointGroup;
import com.smrtcold.dev.dto.task.defrost.DefrostTask;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 化霜模式1
 */
@Service
public class DefrostMode1Service {

    public List<DefrostTask> scheduleDefrost(
            List<String> runtimePeriods,
            List<PointGroup> pointGroups) {

        // 1. 解析所有电价时间段并合并
        List<int[]> mergedPeriods = parseAndMergeRuntimePeriods(runtimePeriods);

        // 2. 按开始时间排序所有时间段
        mergedPeriods.sort(Comparator.comparingInt(a -> a[0]));

        // 3. 计算所有组的总任务列表
        List<DefrostTask> allTasks = new ArrayList<>();

        // 4. 当前时间指针（分钟）和当前时间段索引
        int currentTime = 0;
        int periodIndex = 0;

        // 5. 遍历所有设备组
        for (PointGroup group : pointGroups) {
            // 6. 获取组配置参数
            int defrostTime = group.getDefrostTime();
            int interval = group.getInterval();
            int fanCount = group.points.size();
            // 7. 为组内每个风机安排时间
            for (int i = 0; i < fanCount; i++) {
                Point fan = group.points.get(i);

                // 8. 寻找合适的时间段位置
                if (!findNextAvailableSlot(mergedPeriods, defrostTime, periodIndex, currentTime)) {
                    // 无法找到合适的时间段，跳过该风机
                    continue;
                }
                // 9. 更新当前时间段索引
                periodIndex = findCurrentPeriodIndex(mergedPeriods, currentTime);

                // 10. 创建化霜任务
                allTasks.add(new DefrostTask(group.getDevid() + ":" + group.name + ":", fan, currentTime, defrostTime));


                // 11. 更新当前时间（下一个风机开始时间）
                currentTime += defrostTime;
                // 12. 添加间隔时间（最后一个风机不加间隔）
                if (i < fanCount - 1) {
                    currentTime += interval;
                }
            }
        }
        // 13. 按开始时间排序所有任务
        allTasks.sort(Comparator.comparingInt(task ->
                (task.startHour * 60 + task.startMinute + 1440) % 1440
        ));
        return allTasks;
    }

    // 寻找下一个可用时间段位置
    private boolean findNextAvailableSlot(List<int[]> periods, int duration,
                                          int startPeriodIndex, int currentTime) {
        // 从当前时间段开始检查
        for (int i = startPeriodIndex; i < periods.size(); i++) {
            int[] period = periods.get(i);
            int periodStart = period[0];
            int periodEnd = period[1];

            // 如果当前时间小于时间段开始时间，跳到时间段开始
            if (currentTime < periodStart) {
                currentTime = periodStart;
            }

            // 检查时间段剩余容量
            if (currentTime + duration <= periodEnd) {
                return true;
            }

            // 如果当前时间段不够，尝试下一个时间段
            if (i < periods.size() - 1) {
                // 跳到下一个时间段的开始
                currentTime = periods.get(i + 1)[0];
            }
        }
        return false;
    }

    // 找到当前时间所在的时间段索引
    private int findCurrentPeriodIndex(List<int[]> periods, int currentTime) {
        for (int i = 0; i < periods.size(); i++) {
            int[] period = periods.get(i);
            if (currentTime >= period[0] && currentTime < period[1]) {
                return i;
            }
        }
        return 0; // 默认返回第一个时间段
    }

    // 解析并合并时间段
    private List<int[]> parseAndMergeRuntimePeriods(List<String> periods) {
        // 1. 解析所有时间段
        List<int[]> allPeriods = new ArrayList<>();
        for (String period : periods) {
            String[] parts = period.split("-");
            int start = timeToMinutes(parts[0].trim());
            int end = timeToMinutes(parts[1].trim());

            if (end <= start) {
                // 跨天时间段：拆分为两段
                allPeriods.add(new int[]{start, 1440});
                allPeriods.add(new int[]{0, end});
            } else {
                allPeriods.add(new int[]{start, end});
            }
        }

        // 2. 合并重叠的时间段
        if (allPeriods.isEmpty()) return allPeriods;

        allPeriods.sort(Comparator.comparingInt(a -> a[0]));
        List<int[]> merged = new ArrayList<>();
        int[] current = allPeriods.get(0);

        for (int i = 1; i < allPeriods.size(); i++) {
            int[] next = allPeriods.get(i);
            if (current[1] >= next[0]) {
                // 合并重叠的时间段
                current[1] = Math.max(current[1], next[1]);
            } else {
                merged.add(current);
                current = next;
            }
        }
        merged.add(current);

        return merged;
    }

    // 时间转换工具方法
    private int timeToMinutes(String time) {
        String[] parts = time.split(":");
        return Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]);
    }

}
